Promise 是 ES6 新出的 API 主要用于解决繁琐的异步回调问题。

** 回调地狱 写法**  

```js
// 如果我们有多个请求，后面的请求依赖前面的请求
$.get("url1", (data1) => {
  // xxx
  $.get(data1.url, (data2) => {
    // xxx
    $.get(data2.url, (data3) => {
      // xxxx
    });
  });
});
```

## Promise 三种状态

- 待定（pending）：初始状态，既没有被兑现，也没有被拒绝。
- 已兑现（fulfilled）：意味着操作成功完成。
- 已拒绝（rejected）：意味着操作失败。


pending -> resolved  
pending -> rejected



** Promise 写法**

```js
// 链式调用
$.get("url1", (data1) => {
  return new Promise((resolve,reject)) => {
    resolve(data1)
}}).then(data2 => {
    // xxxxx
  }).then(data3 => {
    // xxxxx
  });
```
:::tip 请注意
Promise 本身是同步执行的，里面放入异步代码
pending 状态，不会触发 then 和 catch  
resolved 状态，会触发后续的 then 回调函数  
rejected 状态，会触发后续的 catch 回调函数  
then 正常返回 resolved，里面有报错则返回 rejected  
catch 正常返回 resolved，里面有报错则返回 rejected
:::

Promise then catch 链式调用，但也是基于回调函数


## Promise 小测试

```js
// 会打印哪些数字
Promise.resolve()
  .then(() => {
    console.log(1);
  })
  .catch(() => {
    console.log(2);
  })
  .then(() => {
    console.log(3);
  });

// 1，3
```

```js
// 会打印哪些数字
Promise.resolve()
  .then(() => {
    console.log(1);
    throw new Error("errol");
  })
  .catch(() => {
    console.log(2);
  })
  .then(() => {
    console.log(3);
  });
// 1,2,3
```

```js
// 会打印哪些数字
Promise.resolve()
  .then(() => {
    console.log(1);
    throw new Error("errol");
  })
  .catch(() => {
    console.log(2);
  })
  .catch(() => {
    // 这里是catch
    console.log(3);
  });

// 1,2
```

## async/await

async/await 是 Promise 的语法糖。将异步变成同步，彻底消灭回调函数(callback hell)

- 示例
```js
// 语法糖 (将异步变为同步执行)
async function getResult() {
  console.log(1);
  const result1 = await ajax1(); // 等待结果并跳出（暂停）函数，执行后面的结果，再回来执行后面的
  console.log(3)
  const result2 = await ajax2();
  console.log(4)
}
console.log(2);

// 1,2,3,4
```

## async 小测试

```js
// 请注意里面有个坑
async function fn() {
  console.log("start");
  const a = await 100;
  console.log("a", a);
  const b = await Promise.resolve(200);
  console.log("b", b);
  const c = await Promise.reject(300);
  console.log("c", c);
  console.log("end");
}

fn(); //执行完毕，打印出那些内容？

// --------------分割线------------------

// 填坑  await 相当于 Promise 的 then

async function fn() {
  console.log("start");
  const a = await 100;
  console.log("a", a);
  const b = await Promise.resolve(200);
  console.log("b", b);
  let c = null;
  try {
    c = await Promise.reject(300);
  } catch (err) {
    c = err;
  }
  console.log("c", c);
  console.log("end");
}

fn();
```

async/await 的顺序问题

```js
// 打印顺序
async function async1() {
  console.log("a");
  await async2();
  console.log("b");
}
async function async2() {
  console.log("2");
}
console.log("script start");

setTimeout(function () {
  console.log("setTimeout");
}, 0);

async1();

new Promise(function (resolve) {
  console.log("p1");
  resolve();
}).then(function () {
  console.log("p2");
});
console.log("script end");

// 
```

promise 和 setTimeout 的顺序

```js
// 打印顺序
console.log(100);
setTimeout(() => {
  console.log(200);
});
Promise.resolve().then(() => {
  console.log(300);
});
console.log(400);
```
:::info
执行 async 函数，返回的是 Promise 对象  
JS 还是单线程 ，还得是有异步，还得是基于 event loop
:::

<!-- 
## Promise 加载图片
```js
function loadImg(src) {
  const p = new Promise((resolve, reject) => {
    const img = document.createElement("img");
    img.onload = () => {
      resolve(img);
    };
    img.onerror = () => {
      const err = new Error(`图片加载失败 ${src}`);
      reject(err);
    };
    img.src = src;
  });
  return p;
}

const url1 = "https://img.mukewang.com/5a9fc8070001a82402060220-140-140.jpg";
const url2 = "https://img3.mukewang.com/5a9fc8070001a82402060220-100-100.jpg";

loadImg(url1)
  .then((img1) => {
    console.log(img1.width);
    return img1; // 普通对象
  })
  .then((img1) => {
    console.log(img1.height);
    return loadImg(url2); // promise 实例
  })
  .then((img2) => {
    console.log(img2.width);
    return img2;
  })
  .then((img2) => {
    console.log(img2.height);
  })
  .catch((ex) => console.error(ex));
``` -->

## promise 原理
在 JavaScript 中，Promise 是一种用于处理异步操作的对象。Promise 可以看作是一个包装了异步操作结果的容器，当异步操作成功时，Promise 对象会返回一个包含异步操作结果的值；当异步操作失败时，Promise 对象会返回一个错误对象。

Promise 的基本原理是，通过实例化 Promise 对象并调用其 then() 方法，可以注册一个回调函数，以在异步操作完成时处理操作结果。在异步操作完成之前，Promise 对象的状态为“pending”，当异步操作成功完成时，Promise 对象的状态会变为“fulfilled”，并且会调用 then() 方法中注册的成功回调函数；当异步操作失败时，Promise 对象的状态会变为“rejected”，并且会调用 then() 方法中注册的失败回调函数。

Promise 对象有三种状态：pending（等待状态）、fulfilled（成功完成状态）和 rejected（失败状态）。在 Promise 对象的生命周期中，它的状态只能从“pending”转变为“fulfilled”或“rejected”，一旦状态发生变化，就不能再改变。

Promise 对象的 then() 方法可以接受两个参数：一个成功回调函数和一个失败回调函数，它们分别在异步操作成功和失败时被调用。then() 方法还可以链式调用，这种方式可以让我们更方便地组织异步操作的逻辑，以及处理多个异步操作的结果。

Promise 的基本原理是利用回调函数来处理异步操作的结果，以及通过 Promise 对象的状态来管理异步操作的状态。Promise 对象的使用可以让我们更加优雅地处理异步操作，并提高代码的可读性和可维护性。


## promise A+ 规范详解

## 手写 promise 函数

## 重点注意 then 的链式调用和值的穿透

## 写一个 Promise.allSeettled, 需要返回所有 promise 的状态和结果